local tablet = AceLibrary("Tablet-2.0")
local crayon = AceLibrary("Crayon-2.0")

local L = AceLibrary("AceLocale-2.2"):new("KungFu")

KungFu = AceLibrary("AceAddon-2.0"):new("AceEvent-2.0", "AceConsole-2.0", "AceDB-2.0", "FuBarPlugin-2.0")

KungFu.version       = "2.0." .. string.sub("$Revision: 56547 $", 12, -3)
KungFu.releaseDate   = string.sub("$Date: 2007-12-03 20:53:10 -0500 (Mon, 03 Dec 2007) $", 8, 17)
KungFu.hasIcon = "Interface\\Icons\\Trade_Engineering"
KungFu.canHideText = true
KungFu.clickableTooltip = true

KungFu:RegisterDB("KungFuDB")
KungFu:RegisterDefaults('profile', {
	showBooleanSkills = false
})
KungFu:RegisterDefaults('char', {
	hidden = {},
})

local optionsTable = {
	handler = KungFu,
	type = 'group', pass = true,
	get = function(k) return KungFu.db.profile[k] end,
	set = function(k, t)
		KungFu.db.profile[k] = t
		KungFu:UpdateTooltip()
	end,
	args = {
		showBooleanSkills = {
			type = 'toggle', name = L['Show boolean skills'],
			desc = L["Show skills which are learned/not-learned, but which don't improve through practice"],
		},
	},
}

KungFu:RegisterChatCommand({"/kf", "/kungfu"}, optionsTable)
KungFu.OnMenuRequest = optionsTable

-- Methods

local new, del, newHash, newSet, deepCopy, deepDel, clear
do
	local list = setmetatable({}, {__mode='k'})
	function new(...)
		local t = next(list)
		if t then
			list[t] = nil
			for i = 1, select('#', ...) do
				t[i] = select(i, ...)
			end
			return t
		else
			return { ... }
		end
	end

	function newHash(...)
		local t = next(list)
		if t then
			list[t] = nil
		else
			t = {}
		end
		for i = 1, select('#', ...), 2 do
			t[select(i, ...)] = select(i+1, ...)
		end
		return t
	end

	function del(t)
		for k in pairs(t) do
			t[k] = nil
		end
		t[''] = true
		t[''] = nil
		list[t] = true
		return nil
	end

	function clear(t)
		for k in pairs(t) do
			t[k] = deepDel(t[k])
		end
		t[''] = true
		t[''] = nil
		return t
	end

	function deepDel(t)
		if type(t) ~= "table" then
			return nil
		end
		for k,v in pairs(t) do
			t[k] = deepDel(v)
		end
		return del(t)
	end
end

function KungFu:OnInitialize()
	self.skillList = {}
	self.watch = {
		name = '',
		rank = '',
	}
end

function KungFu:OnEnable()
	self:RegisterEvent("SKILL_LINES_CHANGED","Update") 
	self:RegisterEvent("PLAYER_LEVEL_UP","Update") 
end

function KungFu:OnDataUpdate()
	clear(self.skillList)
	local skillIndex = 0
	local headerIndex = 0
	
	local numSkills = GetNumSkillLines()
	
	for skillIndex=1, numSkills do
		local skillName, isHeader, isExpanded, skillRank, numTempPoints, skillModifier, skillMaxRank, isAbandonable, stepCost, rankCost, minLevel, skillCostType, skillDesc = GetSkillLineInfo(skillIndex)
		
		if isHeader then
			headerIndex = headerIndex + 1
			table.insert(self.skillList, newHash('category', skillName, 'skills', new(), 'nonBooleanSkills', 0))
		elseif headerIndex > 0 then
			if skillMaxRank > 1 then self.skillList[headerIndex].nonBooleanSkills = self.skillList[headerIndex].nonBooleanSkills + 1 end
			table.insert(self.skillList[headerIndex].skills, newHash('name', skillName, 'rank', skillRank, 'maxrank', skillMaxRank, 'rankbonus', skillModifier))
			if skillName == self.watch.name then
				self.watch.rank = crayon:Colorize(crayon:GetThresholdHexColor((skillRank+(skillModifier or 0)) / skillMaxRank), (skillRank+(skillModifier or 0))..'/'..skillMaxRank)
			end
		end
	end
end

function KungFu:OnTextUpdate()
	local text = 'Skills'
	if self.watch.name ~= '' then
		text = self.watch.name..': '..self.watch.rank
	end
	self:SetText(text)
end

function KungFu:OnTooltipUpdate()
	tablet:SetHint(L["|cffeda55fClick|r to open the Skills Panel"])
	
	for _,category in pairs(self.skillList) do
		if category.nonBooleanSkills > 0 or self.db.profile.showBooleanSkills then
			local cat = tablet:AddCategory(
				'id', category.category, 'columns', 2,
				'text', category.category,
				'func', 'ToggleCategory', 'arg1', self, 'arg2', category.category,
				'child_textR', 1, 'child_textG', 1, 'child_textB', 0,
				'showWithoutChildren', true,
				'checked', true, 'hasCheck', true, 'checkIcon', self.db.char.hidden[category.category] and "Interface\\Buttons\\UI-PlusButton-Up" or "Interface\\Buttons\\UI-MinusButton-Up"
			)
			if not self.db.char.hidden[category.category] then
				for _,skill in pairs(category.skills) do
					if skill.maxrank > 1 then
						local rank = skill.rank
						if skill.rankbonus > 0  then
							rank = rank.."(+"..skill.rankbonus..")"
						end
						rank = rank.."/"..skill.maxrank
						local r,g,b = crayon:GetThresholdColor((skill.rank+(skill.rankbonus or 0)) / skill.maxrank)
						cat:AddLine(
							'text', skill.name, 'text2', rank, 
							'text2R', r, 'text2G', g, 'text2B', b,
							'func', 'SetWatchedSkill', 'arg1', self, 'arg2', skill.name)
					elseif self.db.profile.showBooleanSkills then
						cat:AddLine('text', skill.name)
					end
				end
			end
		end
	end
end

function KungFu:OnClick()
	ToggleCharacter("SkillFrame")
end

function KungFu:ToggleCategory(id, button)
	if self.db.char.hidden[id] then
		self.db.char.hidden[id] = false
	else
		self.db.char.hidden[id] = true
	end
	-- Refresh in place
	self:UpdateTooltip()
end

function KungFu:SetWatchedSkill(skillname)
	if self.watch.name ~= skillname then
		self.watch.name = skillname
	else
		self.watch.name = ''
		self.watch.rank = ''
	end
	self:Update()
end
